package xyz.csmcool.imuser.controller;


import io.netty.util.internal.ObjectUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import xyz.csmcool.imuser.entity.Users;
import xyz.csmcool.imuser.entity.vo.*;
import xyz.csmcool.imuser.service.IUsersService;
import xyz.csmcool.imutil.dto.RoomUserDto;
import xyz.csmcool.imutil.dto.RoomUsersDto;
import xyz.csmcool.imutil.dto.UserDto;
import xyz.csmcool.imutil.utils.BeanUtil;
import xyz.csmcool.imutil.utils.ImageUtil;
import xyz.csmcool.imutil.utils.JwtUtils;
import xyz.csmcool.imutil.utils.ResultTool;
import xyz.csmcool.imutil.webVo.MyPage;
import xyz.csmcool.imutil.webVo.RedisService;
import xyz.csmcool.imutil.webVo.ResultCode;
import xyz.csmcool.imutil.webVo.ResultVo;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.IntStream;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author csmcool
 * @since 2022-07-31
 */
@RestController
@RequestMapping("/users")
@Validated
@RequiredArgsConstructor
public class UsersController {

    final IUsersService iUsersService;
    final RedisService redisService;

    @PostMapping("/login")
    public ResultVo login(@Validated @RequestBody UserLoginVo userLoginVo) {
        //验证账户是否被锁定
        Object errorNumObj = redisService.get("errorLogin:" + userLoginVo.getEmail());
        int errorNum = errorNumObj == null ? 0 : (Integer) errorNumObj;
        if (errorNum > 3) {
            return ResultTool.fail(ResultCode.CUSTOM_FAIL.setCode(999).setMessage("错误次数太多，请五分钟后重试"));
        }

        //判断验证码是否正确
        Integer xWidth = (Integer)redisService.get("code:" + userLoginVo.getEmail());
        if (xWidth == null) {
            return ResultTool.fail(ResultCode.CUSTOM_FAIL.setCode(890).setMessage("验证码过期，请刷新"));
        }
        if (userLoginVo.getVerifyCode() > xWidth + 10 || userLoginVo.getVerifyCode() < xWidth -10) {
            return ResultTool.fail(ResultCode.CUSTOM_FAIL.setCode(890).setMessage("验证码错误"));
        }

        //判断是否登陆成功
        Users users = iUsersService.isSuccessLoginAndBackInfo(userLoginVo);
        if (users != null) {
            if (users.getAvailableStatus() == 2) {
                return ResultTool.fail(ResultCode.COMMON_FAIL.setCode(887).setMessage("该邮箱未激活,请激活后重新登陆"));
            }
            Users userInfo = iUsersService.getById(users.getId());
            String jwtToken = JwtUtils.getJwtToken(String.valueOf(users.getId()));
            HashMap<String,Object> map = new HashMap<>(4);
            map.put("token",jwtToken);
            map.put("userInfo",userInfo);
            redisService.set("user:" + users.getId(),userInfo,60 * 60 * 24);

            return ResultTool.success(map);
        } else {
            Object o = redisService.get("errorLogin:" + userLoginVo.getEmail());
            Integer i = o == null ? 1 : (Integer) o + 1;
            redisService.set("errorLogin:"+userLoginVo.getEmail(),i,5 * 60);
            return ResultTool.fail(ResultCode.COMMON_FAIL.setCode(889).setMessage("邮箱或者密码不正确"));
        }
    }

    @GetMapping("/getCode/{email}")
    public ResultVo getCode(@PathVariable String email) {

        Map<String, Object> resultMap = new HashMap<>(8);
        Random rand = new Random();
        int i = rand.nextInt(2);
        try {
            String filePath = "static/assets/a" + i + ".jpg";
            ClassPathResource resource = new ClassPathResource(filePath);
            File inuModel = new File(filePath);
            FileUtils.copyToFile(resource.getInputStream(), inuModel);;
            ImageUtil.createImage(inuModel,resultMap);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultTool.fail(ResultCode.CUSTOM_FAIL.setMessage("获取验证码失败"));
        }
        int xWidth = Integer.parseInt(resultMap.get("xWidth").toString());
        resultMap.remove("xWidth");
        redisService.set("code:" + email,xWidth,60);
        return ResultTool.success(resultMap);
    }

    @PostMapping("/register")
    public ResultVo registerUser(@Validated @RequestBody UserRegisterVo userRegisterVo) {
        iUsersService.registerNewUser(userRegisterVo);
        return ResultTool.success();
    }

    @GetMapping("/active-email/{email}/{code}")
    public ResultVo activeEmail(@PathVariable("code") String code, @PathVariable("email") String email) {
        Boolean aBoolean = iUsersService.activeEmail(email, code);
        if (!aBoolean) {
            return ResultTool.fail(ResultCode.COMMON_FAIL.setCode(893).setMessage("激活出错请稍后重试"));
        }
        return ResultTool.success();
    }

    @GetMapping("/logout")
    public ResultVo logout(HttpServletRequest request) {
        String id = JwtUtils.getMemberIdByJwtToken(request);
        redisService.del("user:" + id);
        return ResultTool.success();
    }

    @PostMapping("/update-info")
    public ResultVo updateInfo(@Validated @RequestBody UserInfoVo userInfoVo,HttpServletRequest request) {
        if (BeanUtil.isAllFiledNull(userInfoVo)) {
            return ResultTool.fail(ResultCode.COMMON_FAIL.setMessage("没有更新内容"));
        }
        String id = JwtUtils.getMemberIdByJwtToken(request);
        userInfoVo.setId(Integer.valueOf(id));
        iUsersService.updateUserInfo(userInfoVo);
        redisService.del("user:" + id);
        Users userInfo = iUsersService.getById(id);
        redisService.set("user:" + id,userInfo,60 * 60 * 24);
        return ResultTool.success(userInfo);
    }

    @PostMapping("/room-user")
    public ResultVo<List<UserDto>> getRoomUserInfo(@RequestParam("userIdList") List<Integer> ids) {
        List<UserDto> userDtos = iUsersService.selectRoomUser(ids);
        return ResultTool.success(userDtos);
    }

    @PostMapping("/search-room-user")
    public ResultVo<RoomUsersDto> getRoomUserInfoByName(@RequestBody RoomUserDto roomUserDto) {
        RoomUsersDto roomUsersDto = iUsersService.selectRoomUserByName(roomUserDto);
        return ResultTool.success(roomUsersDto);
    }

    @PostMapping("/getInfo")
    public ResultVo<UserDto> getUseInfoById(@RequestParam("uid") String uid) {
        Users users = (Users) redisService.get("user:" + uid);
        UserDto userDto = new UserDto();
        BeanUtil.updateProperties(users,userDto);
        return ResultTool.success(userDto);
    }

    @GetMapping("/getSimpleInfo/{id}")
    public ResultVo<UserSimpleVo> getMyFriendSimpleInfo(@PathVariable("id") Integer id) {
        UserSimpleVo userSimpleInfo = iUsersService.getUserSimpleInfo(id);
        return ResultTool.success(userSimpleInfo);
    }

    @PostMapping("/searchUser/{limit}/{page}")
    public ResultVo<MyPage<UserInfosVo>> searchUser(@RequestParam("name") String name,
                                                    @PathVariable("limit") Long limit,
                                                    @PathVariable("page") Long page) {
        if(name.length() > 20) {
            return ResultTool.fail(ResultCode.CUSTOM_FAIL.setMessage("没有查询到用户"));
        }
        MyPage<UserInfosVo> myPage = iUsersService.searchUserByNameOrEmail(page, limit, name, name);
        return ResultTool.success(myPage);
    }

    @GetMapping("/getUserDetailsInfo")
    public ResultVo<UserDetailsVo> getDetailsInfo(HttpServletRequest request,
                                                  @RequestParam("fid") Integer fid) {
        String id = JwtUtils.getMemberIdByJwtToken(request);
        UserDetailsVo userDetails = iUsersService.getUserDetails(Integer.valueOf(id), fid);
        return ResultTool.success(userDetails);
    }
}
